#ifdef _WIN32
#include <process.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#include <unistd.h>
#include "CBoot.h"
#include <sstream>
#include <iostream>


namespace K_Engine
{
	typedef void (*MQCallBack)(void*, std::string);
	typedef void (*TPCallBack)(void*, std::string);
	
	
	void RunDaemon()
	{
		switch(fork())
		{
		case -1:_exit(-1);;
		case 0 :break;
		default:_exit(EXIT_SUCCESS);	
		}
		if( -1 == setsid())_exit(0);;
		switch(fork())
		{
		case -1:_exit(-1);;
		case 0 :break;
		default:_exit(EXIT_SUCCESS);	
		}
		umask(0);
		//chdir("/");
		close(STDIN_FILENO);
	}
	
	
	CBoot::CBoot(std::string conffile):
		m_conffile(conffile)
	{
	}
	
	
	CBoot::~CBoot()
	{
		log.Log("K_Engine退出...",LOG_TYPE::NORMAL);
	}
	
	
	void CBoot::Run()
	{
		std::stringstream ss;
		int pid = -1;
		
#ifdef _WIN32
		pid = _getpid();
#else
		pid = getpid();
#endif
		
		ss<<"K_Engine进程id为 : "<<pid;
		log.Log("K_Engine启动...",LOG_TYPE::NORMAL);
		log.Log(ss.str().c_str(), LOG_TYPE::NORMAL);
		ss.str("");
		
		//初始化配置文件
		if(!conf.LoadConfig(m_conffile))
		{
			log.Log("配置文件加载失败", LOG_TYPE::ERROR);
			log.Log(conf.strGetLastError(), LOG_TYPE::ERROR);
			return;
		}
		else
		{
			log.Log("配置文件加载完毕",LOG_TYPE::NORMAL);
		}
		
		
		//初始化规则文件
		CKRuleManage *rm = CKRuleManage::GetInstance();
		log.Log("开始加载规则",LOG_TYPE::NORMAL);
		int nErr = 0;
		for(int i = 0; i < conf.nSizeOfRule(); i++)
		{
			if(!rm->AddRule(conf.strGetRule(i)))
			{//加载失败
				nErr++;
				log.Log(rm->strGetLastError(), LOG_TYPE::ERROR);
			}
			else
			{//加载成功
				int nFG = conf.strGetRule(i).find("|");
				std::string strTemp = "加载规则 {";
				if(-1 == nFG)
				{//找不到分隔符
					strTemp += conf.strGetRule(i) + "} 成功!";
				}
				else
				{//找到分隔符
					strTemp += conf.strGetRule(i).substr(0, nFG);
					strTemp += "} 成功, 参数为 {" + conf.strGetRule(i).substr(nFG + 1, 
						conf.strGetRule(i).size() - nFG) + "}";
				}
				log.Log(strTemp, LOG_TYPE::NORMAL);
			}
		}
		ss<<"加载规则完毕,一共加载"<<conf.nSizeOfRule();
		ss<<"条规则，成功"<<conf.nSizeOfRule() - nErr;
		ss<<"条，失败"<<nErr<<"条";
		log.Log(ss.str().c_str(),LOG_TYPE::NORMAL);
		ss.str("");
		
		//初始化MQ队列
		if(!mq.init(conf.strGetMsgTempFile()))
		{
			log.Log(mq.strGetLastError(), LOG_TYPE::ERROR);
			return;
		}
		else
		{
			log.Log("消息队列初始化完毕",LOG_TYPE::NORMAL);
		}
		
		//初始化线程池
		if(!threadpool.SetThreadNum(conf.nThreadSize()))
		{
			log.Log(threadpool.strGetLastError(), LOG_TYPE::ERROR);
			return;
		}
		else
		{
			threadpool.Start(&mq, (MQCallBack)&CKMsgQueue::PushMsg);
			log.Log("线程池启动完毕",LOG_TYPE::NORMAL);
		}
		
		//消息队列开始工作
		log.Log("消息队列开始工作",LOG_TYPE::NORMAL);
		mq.MessageLoop(&threadpool, (TPCallBack)&CKThreadPool::SetWork);
	}
}


int main(int argc, char **argv)
{
	// K_Engine::RunDaemon();
	daemon(1, 0);
	std::string param;
	if(2 == argc)
	{
		param = argv[1];
	}
	else
	{
		param = "./conf/KCrawler.json";
	}
	
	K_Engine::CBoot boot(param);
	boot.Run();
	
	return 0;
}
